use axum::{Router, middleware};
use common::base::db;
use common::utils::config_utils::{Config, get_config, load_config};
use main_service::entity::ai_user;
use main_service::middleware::global::{auth, painc};
use main_service::service::user_service;
use main_service::{AppState, controller};
use sea_orm::DatabaseConnection;
use std::panic;
use std::sync::Arc;
use tracing::{error, info};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    //初始化日志
    init_logger();
    //全局异常捕获钩子
    setup_panic_hook();
    // 当前全局状态
    let shared_state: AppState = init_app_state().await;
    //获取端口号
    let port = shared_state.config.server.port.clone();
    //创建app
    let app = create_app(shared_state);
    //创建监听器
    let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port))
        .await
        .unwrap();
    info!("🚀 Server running on port:{}", port);
    //项目启动
    if let Err(e) = axum::serve(listener, app).await {
        error!("server error:{}", e)
    }

    Ok(())
}

async fn init_app_state() -> AppState {
    // 初始化配置
    let config = init_config().await;
    //初始化数据库
    let db: Arc<DatabaseConnection> = db::db_connect(
        &config.database.host,
        &config.database.port,
        &config.database.password,
        &config.database.username,
    )
    .await
    .expect("数据库连接失败");
    //初始化数据库
    AppState {
        config: config.clone(),
        db: db.clone(),
        user_service: user_service::UserService::new(
            db.clone(),
            config.clone(),
        )
        .into(),
    }
}

async fn init_config() -> Arc<Config> {
    let config = match load_config().await {
        Ok(config) => config,
        Err(e) => panic!("{}", e),
    };
    match get_config(&config) {
        Ok(config) => {
            info!("config:{:?}", config);
            Arc::new(config)
        }
        Err(e) => panic!("{}", e),
    }
}

fn setup_panic_hook() {
    panic::set_hook(Box::new(|info| {
        error!("系统异常: {:?}", info);
    }));
}

fn create_app(shared_state: AppState) -> Router {
    Router::new()
        .nest("/api/v1", controller::register())
        // 全局的中间件拦截器
        .route_layer(middleware::from_fn(painc))
        .route_layer(middleware::from_fn(auth))
        .with_state(shared_state)
}

/**
 * 初始化日志
 */
fn init_logger() {
    tracing_subscriber::registry()
        .with(tracing_subscriber::EnvFilter::new(
            //获取环境变量的日志级别
            std::env::var("RUST_LOG").unwrap_or_else(|_| "debug".into()),
        ))
        .with(tracing_subscriber::fmt::layer())
        .init();
}
